cmake_minimum_required(VERSION 3.10)
project(kni LANGUAGES C)

# 检查是否安装了 pkg-config
find_program(PKG_CONFIG pkg-config)
if(NOT PKG_CONFIG)
    message(FATAL_ERROR "pkg-config not found")
endif()

# 检查 DPDK 是否安装
execute_process(
    COMMAND ${PKG_CONFIG} --exists libdpdk
    RESULT_VARIABLE PKG_CONFIG_RESULT
)
if(NOT PKG_CONFIG_RESULT EQUAL 0)
    message(FATAL_ERROR "No installation of DPDK found")
endif()

# 获取 DPDK 的编译和链接选项
execute_process(
    COMMAND ${PKG_CONFIG} --cflags libdpdk
    OUTPUT_VARIABLE DPDK_CFLAGS
    OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
    COMMAND ${PKG_CONFIG} --libs libdpdk
    OUTPUT_VARIABLE DPDK_LDFLAGS_SHARED
    OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
    COMMAND ${PKG_CONFIG} --static --libs libdpdk
    OUTPUT_VARIABLE DPDK_LDFLAGS_STATIC
    OUTPUT_STRIP_TRAILING_WHITESPACE
)

# 检查 pkg-config 是否正确输出了静态链接所需的标志
if("${CMAKE_BUILD_TYPE}" STREQUAL "static")
    if(NOT "${DPDK_LDFLAGS_STATIC}" MATCHES "whole-archive.*no-whole-archive")
        message(WARNING "pkg-config output list does not contain drivers between 'whole-archive'/'no-whole-archive' flags.")
        message(FATAL_ERROR "Cannot generate statically-linked binaries with this version of pkg-config")
    endif()
endif()

# 设置编译选项
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 ${DPDK_CFLAGS}")
add_compile_definitions(ALLOW_EXPERIMENTAL_API)

# 源文件
set(SOURCES main.c)

# 创建构建目录
file(MAKE_DIRECTORY build)

# 动态链接目标
add_executable(kni-shared ${SOURCES})
target_link_libraries(kni-shared PRIVATE pthread ${DPDK_LDFLAGS_SHARED})

# 静态链接目标
add_executable(kni-static ${SOURCES})
target_link_libraries(kni-static PRIVATE pthread ${DPDK_LDFLAGS_STATIC})

# 创建符号链接
add_custom_command(
    TARGET kni-shared POST_BUILD
    COMMAND ln -sf kni-shared build/kni
)
add_custom_command(
    TARGET kni-static POST_BUILD
    COMMAND ln -sf kni-static build/kni
)

# 清理
add_custom_target(clean-all
    COMMAND rm -f build/kni build/kni-static build/kni-shared
    COMMAND test -d build && rmdir build || true
)
